Syntax10.Scn.Fnt Syntax10i.Scn.Fnt StampElems Alloc 2 Feb 95 Syntax10b.Scn.Fnt MODULE DialogElems; (** Markus Knasm ller 22 Jul 94 - IMPORT Dialog, DialogFrames, Dialogs, Display, Files, Input, MenuViewers, Oberon, Printer, TextFrames, TextPrinter, Texts, Viewers; CONST mm = TextFrames.mm; scale = mm DIV 10; minW = 3 * mm; minH = minW; gripW = 15 * scale DIV TextFrames.Unit; gripH = gripW; MR = 0; MM = 1; ML = 2; menu = "System.Close System.Copy System.Grow DialogElems.Update "; TYPE Elem* = POINTER TO ElemDesc; ElemDesc* = RECORD(Texts.ElemDesc) dialog*: Dialogs.Panel; xg*, yg*: INTEGER; sw*, sh*: LONGINT; empty*: BOOLEAN; END; Frame = POINTER TO FrameDesc; FrameDesc = RECORD (DialogFrames.FrameDesc) elem: Elem END; x0, x1, y0, y1: INTEGER; w: Texts.Writer; dUnit, pUnit: LONGINT; PROCEDURE Changed* (e: Elem); VAR t: Texts.Text; pos: LONGINT; BEGIN t := Texts.ElemBase (e); pos := Texts.ElemPos (e); t.notify (t, Texts.replace, pos , pos + 1) END Changed; PROCEDURE FlipGrip (x0, y0, w, h: INTEGER); BEGIN Display.ReplConst (Display.white, x0 + w - gripW, y0, gripW, gripH, Display.invert) END FlipGrip; PROCEDURE SetSize* (e: Elem; w, h: LONGINT); BEGIN IF w < minW THEN w := minW END; IF h < minH THEN h := minH END; e.W := w; e.H := h; e.sw := w; e.sh := h; END SetSize; PROCEDURE box (obj: Dialogs.Object; VAR done: BOOLEAN); VAR x, y, w, h: INTEGER; BEGIN obj.GetDim (x, y, w, h); y := ABS (y); IF x < x0 THEN x0 := x END; IF x1 < x + w THEN x1 := x + w END; IF y - h < y0 THEN y0 := y - h END; IF y1 < y THEN y1 := y END; END box; PROCEDURE Open* (e: Elem; p: Dialogs.Panel; xg, yg: INTEGER; adjust: BOOLEAN); BEGIN e.dialog := p; x0 := MAX (INTEGER); x1 := MIN (INTEGER); y0 := MAX (INTEGER); y1 := MIN (INTEGER); p.Enumerate (box); IF x0 = MAX (INTEGER) THEN e.empty := TRUE; e.xg := 0; e.yg := 0; SetSize (e, 0, 0); ELSE y1 := y1 + y0; x1 := x1 + x0; x0 := 0; y0 := 0; e.empty := FALSE; IF adjust THEN e.xg := -x0; e.yg := - y1; SetSize (e, LONG (x1 - x0) * dUnit, LONG (y1 - y0) * dUnit) ELSE e.xg := xg; e.yg := yg; SetSize (e, e.W, e.H) END END; END Open; PROCEDURE Copy* (se, de: Elem); BEGIN se.W := se.sw; se.H := se.sh; Texts.CopyElem (se, de); Open (de, se.dialog.Copy (), se.xg, se.yg, FALSE) END Copy; PROCEDURE OpenViewer* (e: Elem); VAR v: Viewers.Viewer; f: Frame; x, y: INTEGER; BEGIN NEW (f); f.Open (Dialog.Handle, e.dialog.Copy ()); f.col := 11; f.elem := e; Oberon.AllocateUserViewer (Oberon.Mouse.X, x, y); v := MenuViewers.New (TextFrames.NewMenu ("DialogElems.Panel", menu), f, TextFrames.menuH, x, y) END OpenViewer; PROCEDURE Track (e: Elem; keys: SET; x, y, x0, y0: INTEGER); VAR keysum: SET; x1, y1, w, h: INTEGER; hit: BOOLEAN; BEGIN IF MM IN keys THEN x1 := x - x0; y1 := y - y0; keysum := keys; w := SHORT (e.W DIV dUnit); h := SHORT (e.H DIV dUnit); hit := ~ e.empty & (x1 >= w - gripW) & (0 <= y1) & (y1 < gripH); IF hit THEN FlipGrip (x0, y0, w, h) END; REPEAT Input.Mouse (keys, x, y); Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, x, y); keysum := keysum + keys UNTIL keys = {}; IF hit THEN FlipGrip (x0, y0, w, h) END; IF keysum = {MM} THEN IF hit THEN INC (w, (x - x0) -x1); DEC (h, (y - y0) - y1); SetSize (e, LONG (w) * dUnit, LONG (h) * dUnit); Changed (e) ELSE OpenViewer (e) END END END END Track; PROCEDURE Handle* (e: Texts.Elem; VAR msg: Texts.ElemMsg); VAR e1: Elem; x, y, w, h, res: INTEGER; f: DialogFrames.Frame; p: Dialogs.Panel; BEGIN WITH e: Elem DO WITH msg: TextFrames.DisplayMsg DO IF msg.prepare THEN e.W := e.sw; e.H := e.sh ELSE x := msg.X0; y := msg.Y0; w := SHORT (e.W DIV dUnit); h := SHORT (e.H DIV dUnit); IF e.empty THEN Display.ReplPattern (Display.white, Display.grey1, x, y, w, h, Display.replace) ELSE NEW (f); f.Open (DialogFrames.Handle, e.dialog); f.X := x; f.Y := y; f.W := w; f.H := h; f.Restore(); FlipGrip (x, y, w, h); msg.elemFrame := f END END | msg: TextPrinter.PrintMsg DO IF msg.prepare THEN e.W := 4 * (e.sw DIV dUnit) * pUnit; e.H := 4 * (e.sh DIV dUnit) * pUnit ELSE e.dialog.Print (msg.X0, msg.Y0 + SHORT (e.H DIV pUnit)); e.W := e.sw; e.H := e.sh; END | msg: Texts.IdentifyMsg DO msg.mod := "DialogElems"; msg.proc := "Alloc" | msg: Texts.FileMsg DO IF msg.id = Texts.load THEN NEW (p); p.Load (msg.r); Files.ReadInt (msg.r, e.xg); Files.ReadInt (msg.r, e.yg); Open (e, p, e.xg, e.yg, FALSE) ELSIF msg.id = Texts.store THEN e.W := e.sw; e.H := e.sh; e.dialog.Store (msg.r); Files.WriteInt (msg.r, e.xg); Files.WriteInt (msg.r, e.yg) END | msg: Texts.CopyMsg DO NEW (e1); Copy (e, e1); msg(Texts.CopyMsg).e := e1 | msg: TextFrames.TrackMsg DO Track (e, msg.keys, msg.X, msg.Y, msg.X0, msg.Y0) | msg: TextFrames.FocusMsg DO f := msg.elemFrame (DialogFrames.Frame); f.Restore (); IF msg.focus & (f.panel.cmd[0] # 0X) THEN Dialogs.cmdPanel := f.panel; Oberon.Call (f.panel.cmd, Oberon.Par, FALSE, res) END; IF ~ msg.focus THEN FlipGrip (f.X, f.Y, f.W, f.H) END ELSE END ELSE END END Handle; PROCEDURE Alloc*; VAR e: Elem; BEGIN NEW (e); e.handle := Handle; Texts.new := e; END Alloc; PROCEDURE Insert*; VAR s: Texts.Scanner; text: Texts.Text; beg, end, time: LONGINT; v: Viewers.Viewer; p: Dialogs.Panel; e: Elem; msg: TextFrames.InsertElemMsg; file: Files.File; r: Files.Rider; BEGIN Texts.OpenScanner (s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan (s); IF (s.class = Texts.Char) & (s.c = "^") THEN Oberon.GetSelection (text, beg, end, time); IF time >= 0 THEN Texts.OpenScanner (s, text, beg); Texts.Scan (s) END END; NEW (p); IF (s.class = Texts.Char) & (s.c = "*") THEN v := Oberon.MarkedViewer (); IF (v.dsc # NIL) & (v.dsc.next # NIL) & (v.dsc.next IS DialogFrames.Frame) THEN p := v.dsc.next (DialogFrames.Frame).panel.Copy() END ELSIF s.class = Texts.Name THEN file := Files.Old (s.s); IF file # NIL THEN Files.Set (r, file, 0); p.Load (r); END END; NEW (e); e.handle := Handle; Open (e, p, 0, 0, TRUE); msg.e := e; Oberon.FocusViewer.handle (Oberon.FocusViewer, msg) END Insert; PROCEDURE Update*; VAR v: Viewers.Viewer; f: Frame; r: Texts.Reader; t: Texts.Text; ch: CHAR; BEGIN v := Oberon.Par.vwr; f := v.dsc.next(Frame); t := v.dsc(TextFrames.Frame).text; f.panel.RemoveSelections (); Open (f.elem, f.panel.Copy (), 0, 0, TRUE); Changed (f.elem); Texts.OpenReader (r, t, t.len - 1); Texts.Read (r, ch); IF ch = "!" THEN Texts.Delete (t, t.len - 1, t.len) END END Update; BEGIN dUnit := Dialogs.dUnit; pUnit := Dialogs.pUnit END DialogElems.